#!/usr/bin/env python
import pygtk
import sys, array, os
pygtk.require('2.0')

import gtk, cairo, rsvg
import gnomeapplet

#import subprocess

class PAVolApplet(gtk.EventBox):
    
    #__gsignals__ = { "expose-event": "override" ,
    #                "screen-changed": "override" }
    
    fill = 1.0
    iconpath = "/home/furyy/src/python/pavol/Speaker_Icon.svg"
    def __init__(self,applet):
        gtk.EventBox.__init__(self)
        print "Support for SVG:",self.__has_svg_support()
        #self.svg = rsvg.Handle(file=iconpath)
        self.set_app_paintable(True)
        self.set_visible_window(False)
        
        #Dunno, for transparent cairo draws
        self.picWidth,self.picHeight = 24,24
        self.image = gtk.Image()
        
        self.pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(iconpath, 32,32)
        #image = gtk.Image()
        self.image.set_from_pixbuf(self.pixbuf)
        
        #self.image.set_from_pixbuf(self.make_icon(24,24))
        #self.set_size_request(24,24)
        self.supports_alpha = False
        
        self.applet = applet
        self.applet.set_background_widget(self.applet)
        
        self.applet.connect ("change-size", self.on_change_size)
        self.add(self.image)
        self.tooltips = gtk.Tooltips()
        self.tooltips.set_tip(self, "PAVolControl")
        #: %d%%"%(self.fill*100))

        self.connect("button-press-event",self.pressed)
        #self.connect("scroll-event",self.scrolled)
        applet.connect("change_background", self.onChangeBackground)
        self.connect("size-allocate",self.on_resize)
        self.__setup_applet_menu()
        
    def on_resize(self,w,e):
        if self.picWidth != e.width or self.picHeight!=e.height:
            self.picWidth,self.picHeight = e.width,e.height
            self.image.set_from_pixbuf(self.make_icon(e.width ,e.height ))
            #self.draw_icon(e.width-2,e.height-2)
        pass

    def draw_icon(self,Width,Height):
        ctx = self.window.cairo_create()
        ctx.set_source_pixbuf(self.pixbuf,0,0)
        ctx.set_operator(cairo.OPERATOR_OVER)
        
        ctx.save()
        #ctx.set_source_rgba(0.0, 1.0, 0.0, 0.0)
        #ctx.transform(cairo.Matrix(1,0,0,scale_h,0,0))
        #Allows gradient etc
        linear = cairo.LinearGradient(0, 0, 0, Height)
        linear.add_color_stop_rgba(0,  1, 1, 1, 1)
        linear.add_color_stop_rgba(.4,  0.6, 0.6, 1, .7)
        linear.add_color_stop_rgba(1,  0, 0, 1, 0)
        ctx.set_source(linear)
        ctx.rectangle(0,Height - Height* self.fill,Width,Height)
        ctx.fill()
        ctx.restore()
        self.image.set_from_pixbuf(self.pixbuf)
        
    def make_icon(self,Width,Height):
        return gtk.gdk.pixbuf_new_from_file_at_size(iconpath, Width,Height)
        
        data = array.array('c', chr(0) * Width * Height * 4)
        stride = Width * 4
        surface = cairo.ImageSurface.create_for_data (data, cairo.FORMAT_ARGB32,Width, Height, stride)
        ctx = cairo.Context(surface)
        ctx.set_operator(cairo.OPERATOR_OVER)
        
        ctx.save()
        #ctx.set_source_rgba(0.0, 1.0, 0.0, 0.0)
        #ctx.transform(cairo.Matrix(1,0,0,scale_h,0,0))
        #Allows gradient etc
        linear = cairo.LinearGradient(0, 0, 0, Height)
        linear.add_color_stop_rgba(0,  1, 1, 1, 1)
        linear.add_color_stop_rgba(.4,  0.6, 0.6, 1, .7)
        linear.add_color_stop_rgba(1,  0, 0, 1, 0)
        ctx.set_source(linear)
        ctx.rectangle(0,Height - Height* self.fill,Width,Height)
        ctx.fill()
        ctx.restore()
        
        ctx.set_operator(cairo.OPERATOR_SOURCE)
        ctx.transform(cairo.Matrix(float(Width)/self.svg.props.width,0,0,float(Height)/self.svg.props.height,0,0))
        self.svg.render_cairo(ctx)
        pixbuf = gtk.gdk.pixbuf_new_from_data(data,gtk.gdk.COLORSPACE_RGB, True,8, Width,Height,stride)
        return pixbuf
        #gtk.gdk.pixbuf_new_from_file_at_size("Speaker_Icon.svg", 32,32)
        #image = gtk.Image()
        #image.set_from_pixbuf(self.pixbuf)
        #return image

    def onChangeBackground(self, applet, type, color, pixmap):
        applet.set_style(None)
        rc_style = gtk.RcStyle()
        applet.modify_style(rc_style)
        if (type == gnomeapplet.COLOR_BACKGROUND):
            applet.modify_bg(gtk.STATE_NORMAL, color)
        elif (type == gnomeapplet.PIXMAP_BACKGROUND):
            style = applet.style
            style.bg_pixmap[gtk.STATE_NORMAL] = pixmap
            self.applet.set_style(style)
        
    def do_screen_changed(self,screen, old_screen=None):
        screen = self.get_screen()
        #screen = widget .get_screen()
        colormap = screen.get_rgba_colormap()
        if colormap == None:
            #print 'Your screen does not support alpha channels!'
            colormap = screen.get_rgb_colormap()
            self.supports_alpha = False
        else:
            #print 'Your screen supports alpha channels!'
            self.supports_alpha = True
            
        self.set_colormap(colormap)
        
        return True
    
    #def expose_event(self, image,event ):
    #    image.get_pixbuf().scale_simple(int(event.area.width) , int(event.area.height),
    #                                          gtk.gdk.INTERP_BILINEAR)
        
    # Handle the expose-event by drawing
    #def do_expose_event(self, event):
    #    gtk.EventBox.do_expose_event(self,event)
        
    #def draw(self, cr, w,h):
    #    pass
        
    #def clicked(self,event):
    #    print "Click"
    #    pass

    def pressed(self, obj, event):
        print event.type, event.button
        if event.button == 1:
            os.system('/usr/bin/pavol')

    def scrolled(self, obj, event):
        #print event.type, event.direction
        if event.direction == gtk.gdk.SCROLL_DOWN:
            self.fill = (self.fill - 0.01)
            if self.fill < 0.0:
                self.fill = 0.0
        elif event.direction == gtk.gdk.SCROLL_UP:
            self.fill = (self.fill + 0.01)
            if self.fill > 1.0:
                self.fill = 1.0
        self.image.set_from_pixbuf(self.make_icon(self.picWidth,self.picHeight ))
        self.tooltips.set_tip(self, "PAVol: %d%%"%(self.fill*100))
                
    def on_change_size (self, applet, size):
        self.set_size_request( size, size )

    def __setup_applet_menu(self):
        self.applet.setup_menu_from_file (
            "/home/furyy/src/python/pavol", "applet-menu.xml",
            None, [("Help", lambda a,b: self.msg("Help"),),
            ("About", lambda a,b: self.msg("About"),)
            ])
            
    def msg(self,msg):
        dialog = gtk.MessageDialog(parent=None,
              flags=0,
              type=gtk.MESSAGE_WARNING,
              buttons=gtk.BUTTONS_OK,
              message_format=msg)
        dialog.connect('response', lambda w, id: dialog.destroy())
        dialog.show_all()

    def __has_svg_support (self):
        for format in gtk.gdk.pixbuf_get_formats():
            if format["name"] == "svg":
                return True
        return False

class TransparentWindow(gtk.Window):
    
    __gsignals__ = { "expose-event": "override" ,
                    "screen-changed": "override" }
    
    def __init__(self):
        #gtk.Window.__init__(self)
        super(TransparentWindow,self).__init__()
        self.connect("delete-event", gtk.main_quit)
        self.connect('destroy', self.destroy)
        #self.set_background_svg("player.svg")
        self.supports_alpha = False
        self.do_screen_changed(self)
        self.bgsvg = None

    def do_expose_event(self, event):

        cr = self.window.cairo_create()
        cr.set_operator(cairo.OPERATOR_CLEAR)
        # Ugly but we don't have event.region
        region = gtk.gdk.region_rectangle(event.area)
        cr.region(region)
        cr.fill()
        #
        if self.supports_alpha:
            cr.set_source_rgba(1.0, 1.0, 1.0, 0.0)
        else:
            cr.set_source_rgb(1.0, 1.0, 1.0)
        cr.set_operator(cairo.OPERATOR_SOURCE)
        cr.paint()

        cr.set_operator(cairo.OPERATOR_OVER)

        #print "Trans"
        return False
        
    def set_background_svg(self, fn):
        self.bgsvg = rsvg.Handle(file=fn)
        self.queue_draw()
        
    def destroy(self,e):
        if self.bgsvg:
            self.bgsvg.close()
            
    def do_screen_changed(self,widget, old_screen=None):
        screen = widget.get_screen()
        colormap = screen.get_rgba_colormap()
        if colormap == None:
            #print 'Your screen does not support alpha channels!'
            colormap = screen.get_rgb_colormap()
            self.supports_alpha = False
        else:
            #print 'Your screen supports alpha channels!'
            self.supports_alpha = True
            
        widget.set_colormap(colormap)
        
        return True


def sample_factory(applet, iid):
    applet.add(PAVolApplet(applet))
    applet.show_all()
    return True


if len(sys.argv) == 2:
    if sys.argv[1] == "run-in-window":
        main_window = TransparentWindow() #gtk.Window(gtk.WINDOW_TOPLEVEL)
        main_window.set_title("Python Applet")
        main_window.connect("destroy", gtk.main_quit)
        
        app = gnomeapplet.Applet()
        sample_factory(app, None)
        app.reparent(main_window)
        main_window.show_all()
        gtk.main()
        sys.exit()

gnomeapplet.bonobo_factory("OAFIID:GNOME_PAVolApplet_Factory",
                         gnomeapplet.Applet.__gtype__,
                         "Simple PulseAudio volume control", "1.0", sample_factory)

